/*******************************************************************************
 * Copyright (c) 2011 squid.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     squid - initial API and implementation
 ******************************************************************************/
package com.google.code.cubeirc.ui;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;

import lombok.Getter;
import lombok.Setter;

import org.apache.log4j.Level;
import org.apache.log4j.Priority;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.wb.swt.SWTResourceManager;

import com.google.code.cubeirc.base.BaseTab;
import com.google.code.cubeirc.basequeue.BaseQueue;
import com.google.code.cubeirc.common.ApplicationInfo;
import com.google.code.cubeirc.common.Utils;
import com.google.code.cubeirc.debug.DebuggerQueue;
import com.google.code.cubeirc.debug.EventDebugger;
import com.google.code.cubeirc.editor.EditorManager;
import com.google.code.cubeirc.queue.MessageQueue;
import com.google.code.cubeirc.scripting.Script;
import com.google.code.cubeirc.scripting.ScriptManager;
import com.google.code.cubeirc.tab.TabManager;

public class DebuggerForm extends BaseTab {


	@Getter @Setter
	private EditorManager editor;

	@Getter
	private ActionListener debug_lst;


	@Getter @Setter
	private Boolean isclosing = false;



	@Setter @Getter
	private Composite composite;
	private Table tDebug;
	public DebuggerForm(Composite composite, int style, String name) {
		super(composite, style, name);
		setComposite(composite);
		jbInit();
	}
	@SuppressWarnings({ "deprecation", "unused" })
	private void jbInit() {
		setLayout(new FormLayout());

		StyledText stDebug = new StyledText(this, SWT.BORDER | SWT.V_SCROLL | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY);
		FormData fd_stDebug = new FormData();
		fd_stDebug.left = new FormAttachment(0);
		fd_stDebug.right = new FormAttachment(100);
		stDebug.setLayoutData(fd_stDebug);

		ToolBar toolBar = new ToolBar(this, SWT.FLAT | SWT.RIGHT);
		fd_stDebug.top = new FormAttachment(toolBar, 6);
		FormData fd_toolBar = new FormData();
		fd_toolBar.bottom = new FormAttachment(0, 27);
		fd_toolBar.left = new FormAttachment(0);
		fd_toolBar.right = new FormAttachment(100);
		fd_toolBar.top = new FormAttachment(0);
		toolBar.setLayoutData(fd_toolBar);


		ToolItem tltmsave = new ToolItem(toolBar, SWT.NONE);
		tltmsave.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
			}
		});
		tltmsave.setImage(SWTResourceManager.getImage(DebuggerForm.class, "/com/google/code/cubeirc/resources/img_save.png"));
		tltmsave.setText("&Save");
		tltmsave.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				FileDialog fd = new FileDialog(getComposite().getShell());
				String filename = fd.open();

				if (filename != null)
				{
					getEditor().saveTofile(filename);
					//					new AlertBox(new Shell(), ApplicationInfo.APP_FULL, String.format("Debug output %s saved!", filename), SWT.ICON_INFORMATION | SWT.OK);				
				}								

			}
		});


		ToolItem toolItem = new ToolItem(toolBar, SWT.SEPARATOR);

		ToolItem tltmClear = new ToolItem(toolBar, SWT.NONE);
		tltmClear.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				getEditor().Clear();
			}
		});
		tltmClear.setImage(SWTResourceManager.getImage(DebuggerForm.class, "/com/google/code/cubeirc/resources/img_clear.png"));
		tltmClear.setText("Clear");

		ToolItem toolItem_2 = new ToolItem(toolBar, SWT.SEPARATOR);

		ToolItem tltmLogLevel = new ToolItem(toolBar, SWT.NONE);
		tltmLogLevel.setImage(SWTResourceManager.getImage(DebuggerForm.class, "/com/google/code/cubeirc/resources/img_trash.png"));
		tltmLogLevel.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				Runtime.getRuntime().gc();
			}
		});
		tltmLogLevel.setText("Garbage collector");

		ToolItem toolItem_1 = new ToolItem(toolBar, SWT.SEPARATOR);

		setEditor(new EditorManager("EDITOR_"+getTabName(), stDebug));

		debug_lst = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() instanceof EventDebugger)
				{
					EventDebugger debug_obj = (EventDebugger)e.getSource();
					getEditor().addText(String.format("[%s] [bold]%s[normal] -- %s -- %s", debug_obj.getDatetime(), debug_obj.getLevel().toString(), debug_obj.getSender().toString(), debug_obj.getText()));	
				}				
			}
		};

		DebuggerQueue.addListener(getDebug_lst());
		FormData fd_lblMessageQueueSize = new FormData();
		fd_lblMessageQueueSize.left = new FormAttachment(0, 10);
		fd_lblMessageQueueSize.top = new FormAttachment(0, 299);


		ToolItem sep = new ToolItem(toolBar, SWT.SEPARATOR);
		sep.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {

			}
		});
		Combo cbLevel = new Combo(toolBar, SWT.READ_ONLY);
		cbLevel.add("ALL");
		Priority[] pr = Level.getAllPossiblePriorities();
		for (int i = 0; i< pr.length; i++)
		{
			cbLevel.add(pr[i].toString());
		}
		cbLevel.pack();
		sep.setWidth(cbLevel.getSize().x);
		sep.setControl(cbLevel);
		
		final ToolItem toolItem_3 = new ToolItem(toolBar, SWT.SEPARATOR);
		
		final ToolItem tltmIrcConsole = new ToolItem(toolBar, SWT.NONE);
		tltmIrcConsole.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				TabManager.addTab(ApplicationInfo.TAB_IRCCONSOLE, "/com/google/code/cubeirc/resources/img_debugger.png", true, IrcConsoleForm.class.getName(), new Object[] { TabManager.getTabfolder().getParent(),  SWT.NORMAL, ApplicationInfo.TAB_IRCCONSOLE}, new Class[] {Composite.class, int.class,String.class });
			}
		});
		tltmIrcConsole.setImage(SWTResourceManager.getImage(DebuggerForm.class, "/com/google/code/cubeirc/resources/img_server.png"));
		tltmIrcConsole.setText("IRC Console");



		this.tDebug = new Table(this, SWT.FULL_SELECTION | SWT.VIRTUAL);
		this.tDebug.setLinesVisible(true);
		fd_stDebug.bottom = new FormAttachment(100, -208);
		FormData fd_tDebug = new FormData();
		fd_tDebug.top = new FormAttachment(stDebug, 6);
		fd_tDebug.left = new FormAttachment(0);
		fd_tDebug.right = new FormAttachment(100);
		fd_tDebug.bottom = new FormAttachment(100);
		this.tDebug.setLayoutData(fd_tDebug);
		this.tDebug.setHeaderVisible(true);

		final TableColumn tblclmnName = new TableColumn(this.tDebug, SWT.NONE);
		tblclmnName.setWidth(161);
		tblclmnName.setText("Name");

		final TableColumn tblclmnValue = new TableColumn(this.tDebug, SWT.NONE);
		tblclmnValue.setWidth(100);
		tblclmnValue.setText("Value");


		composite.getDisplay().timerExec(1000, getQueueCheckRunnable());
	}

	@Override
	protected void checkSubclass() {

	}

	private Runnable getQueueCheckRunnable()
	{
		return new Runnable() {

			@Override
			public void run() {		
				addValueTable("MEMORY:",  "");	
				addValueTable("User memory", Utils.reportTraffic(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));				
				addValueTable("Total memory", Utils.reportTraffic(Runtime.getRuntime().totalMemory() ));
				addValueTable("Free memory", Utils.reportTraffic(Runtime.getRuntime().freeMemory() ));
				addValueTable("QUEUES:",  "");	
				addValueTable("Base queue components", Integer.toString(BaseQueue.getComponents().size()) );
				addValueTable("Debugger queue events", Integer.toString(DebuggerQueue.getEvents().size()) );
				addValueTable("Message  queue events", Integer.toString(MessageQueue.getEvents().size()) );
				addValueTable("Debugger queue listeners", Integer.toString(DebuggerQueue.getListeners().size()) );
				addValueTable("Message queue listeners", Integer.toString(MessageQueue.getListeners().size()) );	
				addValueTable("SCRIPTS MANAGER",  "");	
				addValueTable("Script loaded", Integer.toString(ScriptManager.scripts.size()) );	
				
				for (Iterator<Script> it = ScriptManager.scripts.iterator(); it.hasNext();)
				{
					Script f = it.next();
					addValueTable(f.getReference().getName(), Utils.reportTraffic(f.getReference().length()) );
				}

				if (!composite.getDisplay().isDisposed() || !getIsclosing())
					composite.getDisplay().timerExec(1000, this);
			}
		};
	}

	private void addValueTable(final String key,final String value)
	{

		if (!getIsclosing() && !tDebug.isDisposed())
		{
			TableItem found = null;
			TableItem[] itms = tDebug.getItems();
			for (int i=0;i<itms.length;i++)
			{
				if (itms[i].getText(0).equals(key))
					found = itms[i];
			}

			if (found == null)
				found = new TableItem(tDebug, SWT.NORMAL);


			if (value == "")
			{
				found.setFont(new Font(getDisplay(), getFont().getFontData()[0].getName(), getFont().getFontData()[0].getHeight(), SWT.BOLD));
				found.setBackground(SWTResourceManager.getColor(SWT.COLOR_LIST_SELECTION));
			}
			found.setText(0, key);
			found.setText(1, value);
		}
	}



	@Override
	public boolean Close() {
		setIsclosing(true);
		getEditor().Close();
		BaseQueue.removeComponent(getEditor());
		DebuggerQueue.removeListener(debug_lst);
		this.dispose();
		super.Close();
		return true;
	}
}
